#!/bin/sh

. "$SPEC_PATH/abstract/sql-scripts"

e2e_test_extra_hash() {
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/sql-scripts")"
}

e2e_test_install() {
  kubectl create namespace "$CLUSTER_NAMESPACE"

  kubectl create -n "$CLUSTER_NAMESPACE" secret generic sql-scripts-sakila-user \
    --from-literal=create-sakila-user.sql="CREATE USER sakila WITH PASSWORD 'sakila'"

  kubectl create -n "$CLUSTER_NAMESPACE" configmap sql-scripts-sakila-schema \
    --from-file=create-sakila-schema.sql="$SPEC_PATH/$SPEC_NAME.sakila.sql"

  create_or_replace_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" "2"

  wait_pods_running "$CLUSTER_NAMESPACE" "2"
  WAIT_CLUSTER_BOOTSTRAP_ONLY=true wait_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"
}

e2e_test() {
  run_test "Check that user was created on primary node" check_user_on_primary
  run_test "Check that database was created on primary node" check_database_on_primary
  run_test "Check that schema was created on primary node" check_schema_on_primary
  run_test "Check that user was created on replica node" check_user_on_replica
  run_test "Check that database was created on replica node" check_database_on_replica
  run_test "Check that schema was created on replica node" check_schema_on_replica
  run_test "Check wrap in transaction" check_wrap_in_transaction
  run_test "Check store status in database" check_store_status_in_database
  run_test "Check retry on error" check_retry_on_error
  run_test "Check continue on error" check_continue_on_error
  run_test "Check do not continue on error" check_dont_continue_on_error
}

check_wrap_in_transaction() {
  local DATABASE="${DATABASE:-sakila}"
  if wait_until eval 'kubectl get sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" -o json \
    | jq -r ".status.managedSql.scripts[1].scripts[3].failureCode" | grep -qxF 25001' \
    && ! run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_wrap_in_transaction$"
  then
    success "wrap in transaction rollback successfully"
  else
    fail "wrap in transaction didn't rollback"
  fi

  kubectl patch sgscript -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME-scripts" \
    --type json -p '[{"op":"replace","path":"/spec/scripts/3/script","value":"CREATE TABLE test_wrap_in_transaction();"}]'

  if wait_until eval 'run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_wrap_in_transaction$"'
  then
    success "wrap in transaction worked successfully"
  else
    fail "wrap in transaction didn't worked"
  fi
}

check_store_status_in_database() {
  local DATABASE="${DATABASE:-sakila}"
  if wait_until eval 'kubectl get sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" -o json \
    | jq -r ".status.managedSql.scripts[1].scripts[4].failureCode" | grep -qxF 25001' \
    && ! run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_store_status_in_database$"
  then
    success "store status in database rollback successfully"
  else
    fail "store status in database didn't rollback"
  fi

  kubectl patch sgscript -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME-scripts" \
    --type json -p '[{"op":"replace","path":"/spec/scripts/4/script","value":"CREATE TABLE test_store_status_in_database();"}]'

  if wait_until eval 'run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_store_status_in_database$"'
  then
    success "store status in database worked successfully"
  else
    fail "store status in database didn't worked"
  fi
}

check_retry_on_error() {
  local DATABASE="${DATABASE:-sakila}"
  if wait_until eval 'run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_retry_on_error$"'
  then
    success "retry on error worked successfully"
  else
    fail "retry on error didn't worked"
  fi
}

check_continue_on_error() {
  local DATABASE="${DATABASE:-sakila}"
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGScript
metadata:
  namespace: $CLUSTER_NAMESPACE
  name: $CLUSTER_NAME-continue-on-error
spec:
  continueOnError: true
  scripts:
  - database: $DATABASE
    script: SELECT * FROM missing_table;
  - database: $DATABASE
    script: CREATE TABLE test_continue_on_error();
EOF
  kubectl patch sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" --type json \
    -p '[{"op":"add","path":"/spec/managedSql/scripts/2","value":{"sgScript":"'"$CLUSTER_NAME-continue-on-error"'"}}]'
  if wait_until eval 'run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_continue_on_error$"'
  then
    success "continue on error worked successfully"
  else
    fail "continue on error didn't worked"
  fi
}

check_dont_continue_on_error() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGScript
metadata:
  namespace: $CLUSTER_NAMESPACE
  name: $CLUSTER_NAME-dont-continue-on-error
spec:
  continueOnError: false
  scripts:
  - database: $DATABASE
    script: SELECT * FROM missing_table;
  - database: $DATABASE
    script: CREATE TABLE test_dont_continue_on_error();
EOF
  kubectl patch sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" --type json \
    -p '[{"op":"add","path":"/spec/managedSql/scripts/3","value":{"sgScript":"'"$CLUSTER_NAME-dont-continue-on-error"'"}}]'
  local DATABASE="${DATABASE:-sakila}"
  if wait_until -t 10 eval 'run_query -p 5432 -i "1" -h "$CLUSTER_NAME" -c "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -q "SELECT tablename FROM pg_tables;" -d "$DATABASE" \
    | grep -q "^test_dont_continue_on_error$"'
  then
    fail "don't continue on error didn't worked"
  else
    success "don't continue on error worked successfully"
  fi
}
